Skip to content

feat(generated): Add new event types, fields, and membership with user support#247

Open
workos-sdk-automation[bot] wants to merge 1 commit intomainfrom
oagen/spec-update-91fc76ae21e088f16365ddfab59bf9c29940d135
Open

feat(generated): Add new event types, fields, and membership with user support#247
workos-sdk-automation[bot] wants to merge 1 commit intomainfrom
oagen/spec-update-91fc76ae21e088f16365ddfab59bf9c29940d135

Conversation

@workos-sdk-automation
Copy link
Copy Markdown
Contributor

Summary

  • New Classes: Added DsyncTokenCreated, DsyncTokenCreatedData, DsyncTokenDeleted event classes for directory token lifecycle events
  • New Class: Added UserOrganizationMembershipBaseWithUser to return organization memberships with embedded user data
  • New Fields: Added Name property to DirectoryUser, DirectoryUserWithGroups, DsyncUserUpdatedData, Profile, and OrganizationMembership classes
  • New Enum Value: Added AdminPortal to EventContextActorSource enum
  • API Changes: Modified ListMembershipsForResourceAsync and ListMembershipsForResourceByExternalIdAsync methods to return UserOrganizationMembershipBaseWithUser instead of UserOrganizationMembershipBaseListData
  • Deprecation Update: Updated deprecation notice for DirectoryUserWithGroups.Groups field with migration guidance
  • Test Updates: Updated test data and authorization service tests to use new return types and fixture files

Triggered by workos/openapi-spec@91fc76a

@workos-sdk-automation workos-sdk-automation Bot requested a review from a team as a code owner April 30, 2026 20:02
@workos-sdk-automation workos-sdk-automation Bot added the autogenerated Autogenerated code or content label Apr 30, 2026
@workos-sdk-automation workos-sdk-automation Bot requested a review from a team as a code owner April 30, 2026 20:02
@workos-sdk-automation workos-sdk-automation Bot added the autogenerated Autogenerated code or content label Apr 30, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 30, 2026

Greptile Summary

This auto-generated PR adds two new directory token lifecycle events (dsync.token.created / dsync.token.deleted), a new UserOrganizationMembershipBaseWithUser class, Name fields on several user-related entities, an AdminPortal enum value, and switches the ListMembershipsForResource* authorization methods to return the new with-user type (a breaking API change).

  • P1 – OrganizationMembership.User declared non-nullable without null test coverage: User User { get; set; } = default! suppresses compiler warnings, but neither the _nulls fixture nor any test covers a response where user is absent. If any existing endpoint omits the field, callers will get a NullReferenceException at runtime.
  • P2 – DsyncTokenDeleted.Data typed as DsyncTokenCreatedData: Both token events share the same payload shape today, so this works, but reusing the created-event's data class for the deleted event is confusing and will be a source of churn if the schemas ever diverge.

Confidence Score: 3/5

Safe to merge with low risk if the API guarantees user is always present in OrganizationMembership responses; a null-safety gap warrants verification before merging.

A P1 finding exists around the non-nullable User property on OrganizationMembership with no null-case test coverage, which could cause NullReferenceExceptions at runtime if the API ever omits the field. The P2 naming issue on DsyncTokenDeleted.Data does not affect correctness today.

src/WorkOS.net/Entities/OrganizationMembership.cs and the corresponding organization_membership_nulls.json fixture need attention to confirm or fix null-safety for the new User property.

Important Files Changed

Filename Overview
src/WorkOS.net/Entities/OrganizationMembership.cs Added non-nullable User User { get; set; } = default!; null-forgiving operator used, and no test covers a missing user field in the nulls fixture.
src/WorkOS.net/Entities/DsyncTokenDeleted.cs New event class for dsync.token.deleted; Data is typed as DsyncTokenCreatedData instead of a dedicated DsyncTokenDeletedData, which is potentially confusing.
src/WorkOS.net/Entities/UserOrganizationMembershipBaseWithUser.cs New class representing organization membership with embedded User object; mirrors OrganizationMembership structure with a GetCustomAttributesAttribute<T> helper.
src/WorkOS.net/Services/Authorization/AuthorizationService.cs Breaking change: ListMembershipsForResource* and ListMembershipsForResourceByExternalId* methods now return UserOrganizationMembershipBaseWithUser instead of UserOrganizationMembershipBaseListData.
src/WorkOS.net/Entities/DsyncTokenCreated.cs New event class for dsync.token.created; correctly wired to DsyncTokenCreatedData.
src/WorkOS.net/Client/Utilities/EventSchemaDiscriminatorConverter.cs Added dsync.token.created and dsync.token.deleted discriminator cases; correctly placed and ordered.
src/WorkOS.net/Enums/EventContextActorSource.cs Added AdminPortal enum value with correct [EnumMember(Value = "admin_portal")] attribute.
test/WorkOSTests/Tests/AuthorizationServiceTest.cs Updated all four membership-list tests to use the new UserOrganizationMembershipBaseWithUser type and matching fixture files.

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class OrganizationMembership {
        +string Id
        +string UserId
        +string OrganizationId
        +OrganizationMembershipCreatedDataStatus Status
        +bool DirectoryManaged
        +string? OrganizationName
        +Dictionary CustomAttributes
        +DateTimeOffset CreatedAt
        +DateTimeOffset UpdatedAt
        +AddRolePermission Role
        +User User  NEW non-nullable
    }
    class UserOrganizationMembershipBaseWithUser {
        +string Id
        +string UserId
        +string OrganizationId
        +OrganizationMembershipCreatedDataStatus Status
        +bool DirectoryManaged
        +string? OrganizationName
        +Dictionary CustomAttributes
        +DateTimeOffset CreatedAt
        +DateTimeOffset UpdatedAt
        +User User
    }
    class DsyncTokenCreated {
        +DsyncTokenCreatedData Data NEW
        +EventContext? Context
    }
    class DsyncTokenDeleted {
        +DsyncTokenCreatedData Data NEW reuses Created type
        +EventContext? Context
    }
    class DsyncTokenCreatedData {
        +string Object
        +string Id
        +string DirectoryId
        +string? OrganizationId
        +string TokenSuffix
        +DateTimeOffset CreatedAt
        +DateTimeOffset? ExpiresAt
    }
    class User {
        +string Id
        +string Email
        +string? FirstName
        +string? LastName
    }
    DsyncTokenCreated --> DsyncTokenCreatedData : Data
    DsyncTokenDeleted --> DsyncTokenCreatedData : Data shared
    OrganizationMembership --> User : User non-nullable
    UserOrganizationMembershipBaseWithUser --> User : User
Loading

Reviews (1): Last reviewed commit: "feat(generated): Add new event types, fi..." | Re-trigger Greptile

{

/// <summary>The event payload.</summary>
public new DsyncTokenCreatedData Data { get; set; } = default!;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 DsyncTokenDeleted.Data typed as DsyncTokenCreatedData

DsyncTokenDeleted reuses DsyncTokenCreatedData for its Data property. While both events share the same directory-token payload shape today, naming the delete event's data type after the create event is misleading — callers inspecting event.Data.GetType() or reading the property signature will see DsyncTokenCreatedData, which could cause confusion or misdirection when the schemas diverge in the future.

A dedicated DsyncTokenDeletedData class (or at minimum a shared DirectoryTokenData base) would make the intent clearer, consistent with how the rest of the SDK models paired event types (e.g., separate Data types per event class).

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +49 to +50
/// <summary>The user that belongs to the organization through this membership.</summary>
public User User { get; set; } = default!;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Non-nullable User may silently be null

User User { get; set; } = default! uses the null-forgiving operator to suppress compiler warnings, but if any existing endpoint that returns OrganizationMembership doesn't embed the user object (e.g., older API responses, or endpoints that don't expand user data), accessing .User will throw a NullReferenceException at runtime with no compile-time warning.

If the API only conditionally includes user, the property should be declared nullable (User? User). If it is always present, this is fine — but even then, the _nulls test fixture (organization_membership_nulls.json) now also always includes a fully populated user object, meaning the null case for this field isn't covered by any test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autogenerated Autogenerated code or content

Development

Successfully merging this pull request may close these issues.

0 participants